package com.ziroom.finance.rabbitmq.common.interceptor;

import com.ziroom.finance.rabbitmq.common.util.UUIDUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * Created by zhanjunwei on 15/7/30.
 */
public class CommonControllerInterceptor extends HandlerInterceptorAdapter {

    private static Logger logger = LoggerFactory.getLogger(CommonControllerInterceptor.class);

    protected ThreadLocal<HttpServletResponse> response = new ThreadLocal<HttpServletResponse>();

    public HttpServletResponse getResponse() {
        return response.get();
    }

    public void setResponse(HttpServletResponse response) {
        this.response.set(response);
    }

    /**
     * 在业务处理器处理请求之前被调用
     * 如果返回false
     * 从当前的拦截器往回执行所有拦截器的afterCompletion(),再退出拦截器链
     * <p>
     * 如果返回true
     * 执行下一个拦截器,直到所有的拦截器都执行完毕
     * 再执行被拦截的Controller
     * 然后进入拦截器链,
     * 从最后一个拦截器往回执行所有的postHandle()
     * 接着再从最后一个拦截器往回执行所有的afterCompletion()
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //设置请求唯一值
        String uuid = request.getParameter("uuid");
        if (!StringUtils.isBlank(uuid)) {
            String oldThreadName = Thread.currentThread().getName();
            Thread.currentThread().setName(oldThreadName + "_uuid:" + uuid);
        } else {
            String oldThreadName = Thread.currentThread().getName();
            Thread.currentThread().setName(oldThreadName + "_uuid:" + UUIDUtils.random().substring(0, 16));
        }

        //打印请求日志
        StringBuilder logUrlSb = new StringBuilder(request.getRequestURI());
        logUrlSb.append("?");
        Map<String, String[]> params = request.getParameterMap();
        for (String key : params.keySet()) {
            String[] values = params.get(key);
            for (String value : values) {
                logUrlSb.append(key);
                logUrlSb.append("=");
                logUrlSb.append(value);
                logUrlSb.append("&");
            }
        }
        String logUrl = logUrlSb.toString();
        if (logUrl.endsWith("&")) {
            logUrl = logUrl.substring(0, logUrl.lastIndexOf('&'));
        } else if (logUrl.endsWith("?")) {
            logUrl = logUrl.substring(0, logUrl.lastIndexOf('?'));
        }
        logger.info(logUrl);
        return true;
    }


    /* (non-Javadoc)
    * @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#postHandle(javax.servlet.http.HttpServletRequest,
    * javax.servlet.http.HttpServletResponse, java.lang.Object, org.springframework.web.servlet.ModelAndView)
    *
    *
    */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        super.postHandle(request, response, handler, modelAndView);
    }


    /**
     * 在DispatcherServlet完全处理完请求后被调用
     * 当有拦截器抛出异常时,会从当前拦截器往回执行所有的拦截器的afterCompletion()
     * (non-Javadoc)
     * @see org.springframework.web.servlet.HandlerInterceptor#afterCompletion(HttpServletRequest,
     * HttpServletResponse, Object, Exception)
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        String oldThreadName = Thread.currentThread().getName();
        if (oldThreadName.contains("_uuid:")) {
            Thread.currentThread().setName(oldThreadName.substring(0, oldThreadName.indexOf("_uuid:")));
        }
    }
}
